Started: 2020-09-10
Last edited: 2020-09-16 20:00:32

library(tidyverse)

# single cell
library(Seurat)

# plotting
library(patchwork)
library(ggthemes)

1 Background

Alice had performed bulk-RNA seq on the placenta sample from COVID-19 positive mothers and control placentas and has a list of genes that were differentially expressed. Here we will use the single-cell RNA seq data to figure out in which cell types those DE genes are expressed.

2 Data

I have already annotated the clusters. The annotated data (a seurat object) was saved as .rds, which we have to read.

seur <- readRDS("../results/02_annotation/seurat-object_annotated.rds")
# set active assay
DefaultAssay(seur) <- "SCT"

# set levels for idents (use merged_annotations)
seur@meta.data$annotation_merged <- factor(seur@meta.data$annotation_merged,
                                           levels = sort(unique(seur@meta.data$annotation_merged)))

# set idents
Idents(seur) <- seur@meta.data$annotation_merged

3 DE genes

Below are the DE genes sent by Alice.

genes <- list()

genes$focused <- c("HSPA1A", "PPP1R11", "LY6GLY6C", "ITGAX", "IFITM1", "C1QC", "CCL2", "OAS3", "MX1")
genes$analysis1 <- c("HSPA1A", "FMC1-LUC7L2", "HSPA1B", "AC011511.4", "PPP1R11", "AL139300.1", "LY6GLY6C")
genes$analysis2 <- c("ITGAX", "OAS3", "IFITM1", "MX1", "C1QC", "MX2", "CCL2")
genes$additional <- c("C1QTNF2", "LYVE1", "TREM1", "FOLR2", "C1QB", "CCL2", "TNFRSF10C", "CXCL9", "IL1R2", "IL36A", "CD28", "OAS1", "IL1RN", "CD36", "CXCR2",   "SERPING1", "CXCR1", "TNFRSF10C", "C1QA", "HCST", "IL36A", "IL4R", "LY96", "IL1R2", "CXCR2", "CXCL2", "S100A7", "IFITM3", "SELENOM", "SELENOP", "C3AR1", "CCL2", "CCL8")
genes$entry <- c("ACE2", "TMPRSS2", "BSG", "DPP4", "CTSL", "CTSB", "FURIN")

all.genes <- c(genes$focused, genes$analysis1, genes$analysis2, genes$additional, genes$entry) %>% 
  unique() %>% 
  sort()

4 Plots

4.1 Dotplot for all genes

# dotplot function
DotPlot2 <- function(object = seur, assay = "SCT", features, title = "", ...) {
  p <- DotPlot(object, 
               assay = assay,
               features = features, 
               dot.scale = 4, 
               dot.min = 0.01,
               ...) +
    coord_flip() +
    labs(caption = paste0("sctransform normalized expression"), title = title) +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1),
          panel.grid.minor = element_blank(),
          panel.grid.major = element_line(size = 0.1),
          legend.key.size = unit(0.75, "line"))
  
  return(p)
}
DotPlot2(features = all.genes)
The following requested variables were not found: AC011511.4, AL139300.1, FMC1-LUC7L2, LY6GLY6C

cowplot::ggsave2(last_plot(), 
                 filename = "../results/03_de-genes/plots/dotplot_all-genes.pdf", 
                 width = 6.5, height = 8, units = "in")

4.2 Individual genes

# violin function
VlnPlot2 <- function(object = seur, assay = "SCT", feature, ...) {
  VlnPlot(object = object, 
          features = feature, 
          assay = assay, 
          same.y.lims = FALSE,
          split.by = "covid", 
          split.plot = TRUE,
          pt.size = 0,
          ...) + 
    theme_minimal() +
    theme(legend.position = "bottom",
          panel.grid.minor = element_blank(),
          panel.grid.major = element_line(size = 0.2),
          axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5),
          legend.key.size = unit(0.75, "lines"))
}
# umap function
FeaturePlot2 <- function(object = seur, feature, ...) {
  DefaultAssay(object) <- "SCT"
  FeaturePlot(object, 
              feature = feature, 
              split.by = "covid",
              pt.size = 0.1, 
              order = TRUE, 
              min.cutoff = "q10", 
              combine = TRUE,
              ...) &
    plot_annotation(title = feature) &
    theme_bw() +
    theme(panel.grid.major = element_line(size = 0.25),
          panel.grid.minor = element_blank(),
          legend.key.size = unit(0.75, "line"),
          legend.text = element_text(size = 8, angle = 90, hjust = 1),
          legend.position = "bottom",
          axis.title = element_text(size = 8),
          plot.title = element_text(size = 12),
          axis.title.y.right = element_blank(),
          axis.text = element_blank(),
          aspect.ratio = 1)
}

for(i in all.genes[all.genes %in% rownames(seur)]) {
  vplot <- VlnPlot2(feature = i)
  fplot <- FeaturePlot2(feature = i, max.cutoff = "q99")
  
  cowplot::ggsave2(vplot, 
                   filename = paste0("../results/03_de-genes/plots/", i, "_violinplot.pdf"),
                   width = 6, height = 3.5, units = "in")
  
  cowplot::ggsave2(fplot, 
                   filename = paste0("../results/03_de-genes/plots/", i, "_on-umap.png"),
                   width = 5, height = 4, units = "in")
  
  vf <- vplot + fplot + 
    plot_layout(guides = "collect", ncol = 1, widths = c(1, 1)) + 
    plot_annotation(caption = "sctransform normalized expression")
  print(vf)
}
The default behaviour of split.by has changed.
Separate violin plots are now plotted side-by-side.
To restore the old behaviour of a single split violin,
set split.plot = TRUE.
      
This message will be shown once per session.

For some genes, the umap plots and violin plots seem to disagree with each other. That is, the gene is expressed at higher level in “covid” than “control” according to the violin plot, but the colours appear stronger for “control” on umap plots. I think this is simply because of the differing number of cells from “control” and “covid”. We have fewer cells from “covid” samples (as is evident also on the umap plots), so the lightness or sparseness of blue on umap plots just reflect that. Violin plots on the other hand scale the width of violins to the total number of cells in each group, so this difference is not seen in violin plots.

5 Session Info

sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Mojave 10.14.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] ggthemes_4.2.0  patchwork_1.0.1 Seurat_3.2.1    forcats_0.5.0   stringr_1.4.0   dplyr_1.0.2     purrr_0.3.4    
 [8] readr_1.3.1     tidyr_1.1.2     tibble_3.0.3    ggplot2_3.3.2   tidyverse_1.3.0

loaded via a namespace (and not attached):
  [1] Rtsne_0.15            colorspace_1.4-1      deldir_0.1-28         ellipsis_0.3.1        ggridges_0.5.2       
  [6] fs_1.5.0              spatstat.data_1.4-3   rstudioapi_0.11       farver_2.0.3          leiden_0.3.3         
 [11] listenv_0.8.0         ggrepel_0.8.2         fansi_0.4.1           lubridate_1.7.9       xml2_1.3.2           
 [16] codetools_0.2-16      splines_4.0.2         knitr_1.29            polyclip_1.10-0       jsonlite_1.7.1       
 [21] broom_0.7.0           ica_1.0-2             cluster_2.1.0         dbplyr_1.4.4          png_0.1-7            
 [26] uwot_0.1.8            shiny_1.5.0           sctransform_0.2.1     compiler_4.0.2        httr_1.4.2           
 [31] backports_1.1.9       assertthat_0.2.1      Matrix_1.2-18         fastmap_1.0.1         lazyeval_0.2.2       
 [36] cli_2.0.2             later_1.1.0.1         htmltools_0.5.0       tools_4.0.2           rsvd_1.0.3           
 [41] igraph_1.2.5          gtable_0.3.0          glue_1.4.2            RANN_2.6.1            reshape2_1.4.4       
 [46] spatstat_1.64-1       Rcpp_1.0.5            cellranger_1.1.0      vctrs_0.3.4           nlme_3.1-149         
 [51] lmtest_0.9-38         xfun_0.16             globals_0.12.5        rvest_0.3.6           mime_0.9             
 [56] miniUI_0.1.1.1        lifecycle_0.2.0       irlba_2.3.3           goftest_1.2-2         future_1.18.0        
 [61] MASS_7.3-52           zoo_1.8-8             scales_1.1.1          spatstat.utils_1.17-0 hms_0.5.3            
 [66] promises_1.1.1        parallel_4.0.2        RColorBrewer_1.1-2    yaml_2.2.1            reticulate_1.16      
 [71] pbapply_1.4-3         gridExtra_2.3         rpart_4.1-15          stringi_1.5.3         rlang_0.4.7          
 [76] pkgconfig_2.0.3       matrixStats_0.56.0    lattice_0.20-41       tensor_1.5            ROCR_1.0-11          
 [81] labeling_0.3          htmlwidgets_1.5.1     cowplot_1.1.0         tidyselect_1.1.0      RcppAnnoy_0.0.16     
 [86] plyr_1.8.6            magrittr_1.5          R6_2.4.1              generics_0.0.2        DBI_1.1.0            
 [91] mgcv_1.8-31           pillar_1.4.6          haven_2.3.1           withr_2.2.0           fitdistrplus_1.1-1   
 [96] abind_1.4-5           survival_3.2-3        future.apply_1.6.0    modelr_0.1.8          crayon_1.3.4         
[101] KernSmooth_2.23-17    plotly_4.9.2.1        grid_4.0.2            readxl_1.3.1          data.table_1.13.0    
[106] blob_1.2.1            reprex_0.3.0          digest_0.6.25         xtable_1.8-4          httpuv_1.5.4         
[111] munsell_0.5.0         viridisLite_0.3.0    
LS0tCnRpdGxlOiAiRXhwcmVzc2lvbiBvZiBERSBnZW5lcyIKYXV0aG9yOiAiQXJ1biBDaGF2YW4iCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19mbG9hdDogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKYmlibGlvZ3JhcGh5OiAuLi9yZWZzLmJpYgotLS0KU3RhcnRlZDogMjAyMC0wOS0xMCAgCkxhc3QgZWRpdGVkOiBgciBmb3JtYXQoU3lzLnRpbWUoKSlgCgpgYGB7ciBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKCiMgc2luZ2xlIGNlbGwKbGlicmFyeShTZXVyYXQpCgojIHBsb3R0aW5nCmxpYnJhcnkocGF0Y2h3b3JrKQpsaWJyYXJ5KGdndGhlbWVzKQpgYGAKCgojIEJhY2tncm91bmQKQWxpY2UgaGFkIHBlcmZvcm1lZCBidWxrLVJOQSBzZXEgb24gdGhlIHBsYWNlbnRhIHNhbXBsZSBmcm9tIENPVklELTE5IHBvc2l0aXZlIG1vdGhlcnMgYW5kIGNvbnRyb2wgcGxhY2VudGFzIGFuZCBoYXMgYSBsaXN0IG9mIGdlbmVzIHRoYXQgd2VyZSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQuIEhlcmUgd2Ugd2lsbCB1c2UgdGhlIHNpbmdsZS1jZWxsIFJOQSBzZXEgZGF0YSB0byBmaWd1cmUgb3V0IGluIHdoaWNoIGNlbGwgdHlwZXMgdGhvc2UgREUgZ2VuZXMgYXJlIGV4cHJlc3NlZC4gCgojIERhdGEKSSBoYXZlIGFscmVhZHkgYW5ub3RhdGVkIHRoZSBjbHVzdGVycy4gVGhlIGFubm90YXRlZCBkYXRhIChhIGBzZXVyYXRgIG9iamVjdCkgd2FzIHNhdmVkIGFzIGAucmRzYCwgd2hpY2ggd2UgaGF2ZSB0byByZWFkLiAKCmBgYHtyfQpzZXVyIDwtIHJlYWRSRFMoIi4uL3Jlc3VsdHMvMDJfYW5ub3RhdGlvbi9zZXVyYXQtb2JqZWN0X2Fubm90YXRlZC5yZHMiKQpgYGAKCmBgYHtyfQojIHNldCBhY3RpdmUgYXNzYXkKRGVmYXVsdEFzc2F5KHNldXIpIDwtICJTQ1QiCgojIHNldCBsZXZlbHMgZm9yIGlkZW50cyAodXNlIG1lcmdlZF9hbm5vdGF0aW9ucykKc2V1ckBtZXRhLmRhdGEkYW5ub3RhdGlvbl9tZXJnZWQgPC0gZmFjdG9yKHNldXJAbWV0YS5kYXRhJGFubm90YXRpb25fbWVyZ2VkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gc29ydCh1bmlxdWUoc2V1ckBtZXRhLmRhdGEkYW5ub3RhdGlvbl9tZXJnZWQpKSkKCiMgc2V0IGlkZW50cwpJZGVudHMoc2V1cikgPC0gc2V1ckBtZXRhLmRhdGEkYW5ub3RhdGlvbl9tZXJnZWQKYGBgCgojIERFIGdlbmVzCkJlbG93IGFyZSB0aGUgREUgZ2VuZXMgc2VudCBieSBBbGljZS4gCgpgYGB7cn0KZ2VuZXMgPC0gbGlzdCgpCgpnZW5lcyRmb2N1c2VkIDwtIGMoIkhTUEExQSIsICJQUFAxUjExIiwgIkxZNkdMWTZDIiwgIklUR0FYIiwgIklGSVRNMSIsICJDMVFDIiwgIkNDTDIiLCAiT0FTMyIsICJNWDEiKQpnZW5lcyRhbmFseXNpczEgPC0gYygiSFNQQTFBIiwgIkZNQzEtTFVDN0wyIiwgIkhTUEExQiIsCSJBQzAxMTUxMS40IiwgIlBQUDFSMTEiLCAiQUwxMzkzMDAuMSIsICJMWTZHTFk2QyIpCmdlbmVzJGFuYWx5c2lzMiA8LSBjKCJJVEdBWCIsICJPQVMzIiwgIklGSVRNMSIsICJNWDEiLCAiQzFRQyIsICJNWDIiLCAiQ0NMMiIpCmdlbmVzJGFkZGl0aW9uYWwgPC0gYygiQzFRVE5GMiIsICJMWVZFMSIsICJUUkVNMSIsICJGT0xSMiIsICJDMVFCIiwJIkNDTDIiLCAiVE5GUlNGMTBDIiwgIkNYQ0w5IiwgIklMMVIyIiwgIklMMzZBIiwgIkNEMjgiLCAiT0FTMSIsICJJTDFSTiIsICJDRDM2IiwgIkNYQ1IyIiwJIlNFUlBJTkcxIiwgIkNYQ1IxIiwgIlRORlJTRjEwQyIsICJDMVFBIiwgIkhDU1QiLCAiSUwzNkEiLCAiSUw0UiIsICJMWTk2IiwgIklMMVIyIiwgIkNYQ1IyIiwgIkNYQ0wyIiwgIlMxMDBBNyIsICJJRklUTTMiLCAiU0VMRU5PTSIsICJTRUxFTk9QIiwgIkMzQVIxIiwgIkNDTDIiLCAiQ0NMOCIpCmdlbmVzJGVudHJ5IDwtIGMoIkFDRTIiLCAiVE1QUlNTMiIsICJCU0ciLCAiRFBQNCIsICJDVFNMIiwgIkNUU0IiLCAiRlVSSU4iKQoKYWxsLmdlbmVzIDwtIGMoZ2VuZXMkZm9jdXNlZCwgZ2VuZXMkYW5hbHlzaXMxLCBnZW5lcyRhbmFseXNpczIsIGdlbmVzJGFkZGl0aW9uYWwsIGdlbmVzJGVudHJ5KSAlPiUgCiAgdW5pcXVlKCkgJT4lIAogIHNvcnQoKQpgYGAKCiMgUGxvdHMKIyMgRG90cGxvdCBmb3IgYWxsIGdlbmVzCgpgYGB7cn0KIyBkb3RwbG90IGZ1bmN0aW9uCkRvdFBsb3QyIDwtIGZ1bmN0aW9uKG9iamVjdCA9IHNldXIsIGFzc2F5ID0gIlNDVCIsIGZlYXR1cmVzLCB0aXRsZSA9ICIiLCAuLi4pIHsKICBwIDwtIERvdFBsb3Qob2JqZWN0LCAKICAgICAgICAgICAgICAgYXNzYXkgPSBhc3NheSwKICAgICAgICAgICAgICAgZmVhdHVyZXMgPSBmZWF0dXJlcywgCiAgICAgICAgICAgICAgIGRvdC5zY2FsZSA9IDQsIAogICAgICAgICAgICAgICBkb3QubWluID0gMC4wMSwKICAgICAgICAgICAgICAgLi4uKSArCiAgICBjb29yZF9mbGlwKCkgKwogICAgbGFicyhjYXB0aW9uID0gcGFzdGUwKCJzY3RyYW5zZm9ybSBub3JtYWxpemVkIGV4cHJlc3Npb24iKSwgdGl0bGUgPSB0aXRsZSkgKwogICAgdGhlbWVfbWluaW1hbCgpICsKICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdCA9IDEpLAogICAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDAuMSksCiAgICAgICAgICBsZWdlbmQua2V5LnNpemUgPSB1bml0KDAuNzUsICJsaW5lIikpCiAgCiAgcmV0dXJuKHApCn0KYGBgCgpgYGB7ciBmaWcuYXNwPTEuMiwgZmlnLndpZHRoPTYuNX0KRG90UGxvdDIoZmVhdHVyZXMgPSBhbGwuZ2VuZXMpCgpjb3dwbG90OjpnZ3NhdmUyKGxhc3RfcGxvdCgpLCAKICAgICAgICAgICAgICAgICBmaWxlbmFtZSA9ICIuLi9yZXN1bHRzLzAzX2RlLWdlbmVzL3Bsb3RzL2RvdHBsb3RfYWxsLWdlbmVzLnBkZiIsIAogICAgICAgICAgICAgICAgIHdpZHRoID0gNi41LCBoZWlnaHQgPSA4LCB1bml0cyA9ICJpbiIpCmBgYAoKIyMgSW5kaXZpZHVhbCBnZW5lcwpgYGB7cn0KIyB2aW9saW4gZnVuY3Rpb24KVmxuUGxvdDIgPC0gZnVuY3Rpb24ob2JqZWN0ID0gc2V1ciwgYXNzYXkgPSAiU0NUIiwgZmVhdHVyZSwgLi4uKSB7CiAgVmxuUGxvdChvYmplY3QgPSBvYmplY3QsIAogICAgICAgICAgZmVhdHVyZXMgPSBmZWF0dXJlLCAKICAgICAgICAgIGFzc2F5ID0gYXNzYXksIAogICAgICAgICAgc2FtZS55LmxpbXMgPSBGQUxTRSwKICAgICAgICAgIHNwbGl0LmJ5ID0gImNvdmlkIiwgCiAgICAgICAgICBzcGxpdC5wbG90ID0gVFJVRSwKICAgICAgICAgIHB0LnNpemUgPSAwLAogICAgICAgICAgLi4uKSArIAogICAgdGhlbWVfbWluaW1hbCgpICsKICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iLAogICAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDAuMiksCiAgICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEsIHZqdXN0ID0gMC41KSwKICAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC43NSwgImxpbmVzIikpCn0KYGBgCgpgYGB7cn0KIyB1bWFwIGZ1bmN0aW9uCkZlYXR1cmVQbG90MiA8LSBmdW5jdGlvbihvYmplY3QgPSBzZXVyLCBmZWF0dXJlLCAuLi4pIHsKICBEZWZhdWx0QXNzYXkob2JqZWN0KSA8LSAiU0NUIgogIEZlYXR1cmVQbG90KG9iamVjdCwgCiAgICAgICAgICAgICAgZmVhdHVyZSA9IGZlYXR1cmUsIAogICAgICAgICAgICAgIHNwbGl0LmJ5ID0gImNvdmlkIiwKICAgICAgICAgICAgICBwdC5zaXplID0gMC4xLCAKICAgICAgICAgICAgICBvcmRlciA9IFRSVUUsIAogICAgICAgICAgICAgIG1pbi5jdXRvZmYgPSAicTEwIiwgCiAgICAgICAgICAgICAgY29tYmluZSA9IFRSVUUsCiAgICAgICAgICAgICAgLi4uKSAmCiAgICBwbG90X2Fubm90YXRpb24odGl0bGUgPSBmZWF0dXJlKSAmCiAgICB0aGVtZV9idygpICsKICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoc2l6ZSA9IDAuMjUpLAogICAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIGxlZ2VuZC5rZXkuc2l6ZSA9IHVuaXQoMC43NSwgImxpbmUiKSwKICAgICAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBhbmdsZSA9IDkwLCBoanVzdCA9IDEpLAogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIsCiAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA4KSwKICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyKSwKICAgICAgICAgIGF4aXMudGl0bGUueS5yaWdodCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgIGFzcGVjdC5yYXRpbyA9IDEpCn0KYGBgCgoKYGBge3IgZmlnLndpZHRoPTcsIGZpZy5hc3A9MC44fQoKZm9yKGkgaW4gYWxsLmdlbmVzW2FsbC5nZW5lcyAlaW4lIHJvd25hbWVzKHNldXIpXSkgewogIHZwbG90IDwtIFZsblBsb3QyKGZlYXR1cmUgPSBpKQogIGZwbG90IDwtIEZlYXR1cmVQbG90MihmZWF0dXJlID0gaSwgbWF4LmN1dG9mZiA9ICJxOTkiKQogIAogIGNvd3Bsb3Q6Omdnc2F2ZTIodnBsb3QsIAogICAgICAgICAgICAgICAgICAgZmlsZW5hbWUgPSBwYXN0ZTAoIi4uL3Jlc3VsdHMvMDNfZGUtZ2VuZXMvcGxvdHMvIiwgaSwgIl92aW9saW5wbG90LnBkZiIpLAogICAgICAgICAgICAgICAgICAgd2lkdGggPSA2LCBoZWlnaHQgPSAzLjUsIHVuaXRzID0gImluIikKICAKICBjb3dwbG90OjpnZ3NhdmUyKGZwbG90LCAKICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lID0gcGFzdGUwKCIuLi9yZXN1bHRzLzAzX2RlLWdlbmVzL3Bsb3RzLyIsIGksICJfb24tdW1hcC5wbmciKSwKICAgICAgICAgICAgICAgICAgIHdpZHRoID0gNSwgaGVpZ2h0ID0gNCwgdW5pdHMgPSAiaW4iKQogIAogIHZmIDwtIHZwbG90ICsgZnBsb3QgKyAKICAgIHBsb3RfbGF5b3V0KGd1aWRlcyA9ICJjb2xsZWN0IiwgbmNvbCA9IDEsIHdpZHRocyA9IGMoMSwgMSkpICsgCiAgICBwbG90X2Fubm90YXRpb24oY2FwdGlvbiA9ICJzY3RyYW5zZm9ybSBub3JtYWxpemVkIGV4cHJlc3Npb24iKQogIHByaW50KHZmKQp9CmBgYAoKRm9yIHNvbWUgZ2VuZXMsIHRoZSB1bWFwIHBsb3RzIGFuZCB2aW9saW4gcGxvdHMgc2VlbSB0byBkaXNhZ3JlZSB3aXRoIGVhY2ggb3RoZXIuIFRoYXQgaXMsIHRoZSBnZW5lIGlzIGV4cHJlc3NlZCBhdCBoaWdoZXIgbGV2ZWwgaW4gImNvdmlkIiB0aGFuICJjb250cm9sIiBhY2NvcmRpbmcgdG8gdGhlIHZpb2xpbiBwbG90LCBidXQgdGhlIGNvbG91cnMgYXBwZWFyIHN0cm9uZ2VyIGZvciAiY29udHJvbCIgb24gdW1hcCBwbG90cy4gSSB0aGluayB0aGlzIGlzIHNpbXBseSBiZWNhdXNlIG9mIHRoZSBkaWZmZXJpbmcgbnVtYmVyIG9mIGNlbGxzIGZyb20gImNvbnRyb2wiIGFuZCAiY292aWQiLiBXZSBoYXZlIGZld2VyIGNlbGxzIGZyb20gImNvdmlkIiBzYW1wbGVzIChhcyBpcyBldmlkZW50IGFsc28gb24gdGhlIHVtYXAgcGxvdHMpLCBzbyB0aGUgbGlnaHRuZXNzIG9yIHNwYXJzZW5lc3Mgb2YgYmx1ZSBvbiB1bWFwIHBsb3RzIGp1c3QgcmVmbGVjdCB0aGF0LiBWaW9saW4gcGxvdHMgb24gdGhlIG90aGVyIGhhbmQgc2NhbGUgdGhlIHdpZHRoIG9mIHZpb2xpbnMgdG8gdGhlIHRvdGFsIG51bWJlciBvZiBjZWxscyBpbiBlYWNoIGdyb3VwLCBzbyB0aGlzIGRpZmZlcmVuY2UgaXMgbm90IHNlZW4gaW4gdmlvbGluIHBsb3RzLgoKIyBTZXNzaW9uIEluZm8KYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgo=